package com.tao.design.state

/**
 *
 * @ProjectName:    lab
 * @Package:        com.tao.design.state
 * @ClassName:      State
 * @Description:     java类作用描述
 * @Author:         wangxf
 * @CreateDate:     2022/4/27 15:23
 * @UpdateUser:     更新者
 * @UpdateDate:     2022/4/27 15:23
 * @UpdateRemark:   更新说明
 * @Version:        1.0
 */
/**
 * 通过改变对象内部的状态来控制对象的行为
 *
 * 特点:将状态封装成为单独的类，并将动作委托到 代表当前状态的对象
 *
 * 主要角色： context  state｛ConcreteStateA、concreteStateB｝
 *
 * 策略模式和状态模式的区别
 *
 *      策略模式：客户端 主动指定当前的所使用的 具体策略
 *      状态模式：将一群行为封装到状态对象中 随着状态的改变 当前状态在状态集合中 游走 而客户对当前的状态 感知不到
 *
 *
 * 步骤:
 */
interface State {
    fun insertQuarter()
    fun ejectQuarter()
    fun tumCrank()
    fun dispense()
}

class SoldState(val gumballMachine: GumballMachine) : State {
    override fun insertQuarter() {
    }

    override fun ejectQuarter() {
    }

    override fun tumCrank() {
    }

    override fun dispense() {
    }
}

class SoldOutState(val gumballMachine: GumballMachine) : State {
    override fun insertQuarter() {

    }

    override fun ejectQuarter() {

    }

    override fun tumCrank() {

    }

    override fun dispense() {

    }
}

class NoQuarterState(val gumballMachine: GumballMachine) : State {
    override fun insertQuarter() {
        gumballMachine.setState(gumballMachine.hasQuarterState)

    }

    override fun ejectQuarter() {

    }

    override fun tumCrank() {

    }

    override fun dispense() {

    }
}

class HasQuarterState(val gumballMachine: GumballMachine) : State {
    override fun insertQuarter() {

    }

    override fun ejectQuarter() {

    }

    override fun tumCrank() {

    }

    override fun dispense() {

    }
}

class GumballMachine(val number: Int) {
    val hasQuarterState: State = HasQuarterState(this)
    val noQuarterState: State = NoQuarterState(this)
    val soldState: State = SoldState(this)
    val soldOutState: State = SoldOutState(this)

    lateinit var currentState: State

    init {
        currentState = noQuarterState
    }


    fun setState(state: State) {
        this.currentState = state
    }
}

